package com.hjm.java.utils;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.io.IOException;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class HttpUtils {
    private static final String TAG = "HttpUtils";
    private OkHttpClient client;
    private static final String PREFERENCE_NAME = "HJMPreferences";
    private Context mcontext;
    private Listener listener;

    public HttpUtils() {
        this.client = new OkHttpClient();
    }

    public HttpUtils(Context mcontext, Listener listener) {
        this.mcontext = mcontext;
        this.client = new OkHttpClient();
        this.listener = listener;
    }

    /**
     * post请求
     *
     * @param url      请求地址
     * @param object   请求参数
     * @param callBack 回调
     * @param <T>
     */
    public <T> void post(String url, Object object, Class<T> responseType, HjmObjectCallBack<T> callBack) {
        Request request = new Request.Builder()
                .url(url)
                .post(buildRequestBody(object))
                .build();

        client.newCall(request).enqueue(new HttpCallBack<T>(responseType, callBack));
    }

    public <T> void postByToken(String url, Object object, Class<T> responseType, HjmListCallBack<T> callBack) {
        String token = getTokenFromSharedPreferences(mcontext, "token");
        Request request = new Request.Builder()
                .url(url)
                .post(buildRequestBody(object))
                .addHeader("token", (token == null ? "" : token))
                .build();

        client.newCall(request).enqueue(new HttpListCallBack<T>(responseType, callBack));
    }

    public <T> void postByToken(String url, Object object, Class<T> responseType, HjmObjectCallBack<T> callBack) {
        String token = getTokenFromSharedPreferences(mcontext, "token");
        Request request = new Request.Builder()
                .url(url)
                .post(buildRequestBody(object))
                .addHeader("token", (token == null ? "" : token))
                .build();

        client.newCall(request).enqueue(new HttpCallBack<T>(responseType, callBack));
    }

    public <T> void getList(String url, Class<T> responseType, HjmListCallBack<T> callBack) {
        Request request = new Request.Builder()
                .url(url)
                .build();

        client.newCall(request).enqueue(new HttpListCallBack<T>(responseType, callBack));
    }

    public <T> void getListByToken(String url, Class<T> responseType, HjmListCallBack<T> callBack) {
        String token = getTokenFromSharedPreferences(mcontext, "token");
        Request request = new Request.Builder()
                .url(url)
                .addHeader("token", (token == null ? "" : token))
                .build();

        client.newCall(request).enqueue(new HttpListCallBack<T>(responseType, callBack));
    }

    public <T> void get(String url, Class<T> responseType, HjmObjectCallBack<T> callBack) {
        Request request = new Request.Builder()
                .url(url)
                .build();

        client.newCall(request).enqueue(new HttpCallBack<>(responseType, callBack));
    }

    public <T> void getByToken(String url, Class<T> responseType, HjmObjectCallBack<T> callBack) {
        String token = getTokenFromSharedPreferences(mcontext, "token");
        Request request = new Request.Builder()
                .url(url)
                .addHeader("token", (token == null ? "" : token))
                .build();

        client.newCall(request).enqueue(new HttpCallBack<>(responseType, callBack));
    }

    public <T> void putByToken(String url, Object object, Class<T> responseType, HjmObjectCallBack<T> callBack) {
        String token = getTokenFromSharedPreferences(mcontext, "token");
        Request request = new Request.Builder()
                .url(url)
                .put(buildRequestBody(object))
                .addHeader("token", (token == null ? "" : token))
                .build();

        client.newCall(request).enqueue(new HttpCallBack<>(responseType, callBack));

    }

    public <T> void deleteByToken(String s, Class<T> responseType, HjmObjectCallBack<T> callBack) {
        String token = getTokenFromSharedPreferences(mcontext, "token");
        Request request = new Request.Builder()
                .url(s)
                .delete()
                .addHeader("token", (token == null ? "" : token))
                .build();

        client.newCall(request).enqueue(new HttpCallBack<>(responseType, callBack));
    }

    public RequestBody buildRequestBody(Object object) {
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        if (object == null)
            return RequestBody.create(mediaType, "{}");
        String requestBody = JSONObject.toJSONString(object);
        Log.d(TAG, "buildRequestBody: 请求体构建成功 \n" + requestBody);
        return RequestBody.create(mediaType, requestBody);
    }

    /**
     * 通用回调，只要时一样的返回格式就可以处理
     *
     * @param <T>
     */
    class HttpCallBack<T> implements Callback {
        HjmObjectCallBack<T> callBack;
        Class<T> responseType;

        public HttpCallBack(Class<T> responseType, HjmObjectCallBack<T> callBack) {
            this.callBack = callBack;
            this.responseType = responseType;
        }

        @Override
        public void onFailure(Call call, IOException e) {
            Log.e(TAG, "onFailure: " + e.getMessage());
            callBack.call(false, null, e.getMessage());
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            String responseData = response.body().string();
            Log.d(TAG, "onResponse: " + responseData);
            // 使用Fastjson解析JSON
            JSONObject jsonObject = JSONObject.parseObject(responseData);
            // 提取data和resultCode字段
            int resultCode = jsonObject.getIntValue("resultCode");
            String data = jsonObject.getString("data");
            String message = jsonObject.getString("message");

            if (response.isSuccessful() && resultCode == 200) {
                // 解析data字段，并返回给调用者
                T result;
                // 处理非JSON数据
                if (responseType == String.class) {
                    result = (T) data;
                } else {
                    result = JSONObject.parseObject(data, responseType);
                }
                callBack.call(true, result, message);
            } else {
                callBack.call(false, null, message);
            }
        }
    }

    /**
     * 通用回调，只要时一样的返回格式就可以处理
     *
     * @param <T>
     */
    class HttpListCallBack<T> implements Callback {
        HjmListCallBack<T> callBack;
        Class<T> responseType;

        public HttpListCallBack(Class<T> responseType, HjmListCallBack<T> callBack) {
            this.callBack = callBack;
            this.responseType = responseType;
        }

        @Override
        public void onFailure(Call call, IOException e) {
            Log.e(TAG, "onFailure: " + e.getMessage());
            callBack.call(false, null, e.getMessage());
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            String responseData = response.body().string();
            Log.d(TAG, "onResponse: " + responseData);
            // 使用Fastjson解析JSON
            JSONObject jsonObject = JSONObject.parseObject(responseData);
            // 提取data和resultCode字段
            int resultCode = jsonObject.getIntValue("resultCode");
            String data = jsonObject.getString("data");
            String message = jsonObject.getString("message");

            if (response.isSuccessful() && resultCode == 200) {
                // 解析data字段，并返回给调用者
                JSONArray jsonArray = JSON.parseArray(data);
                List<T> resultList = (List<T>) jsonArray.toJavaList(responseType);
                Log.d(TAG, "onResponse: 转换的数据大小 " + resultList.size());
                callBack.call(true, resultList, message);
            } else {
                callBack.call(false, null, message);
            }
        }
    }

    /**
     * 获取token
     *
     * @param context
     * @return
     */
    public static String getTokenFromSharedPreferences(Context context, String key) {
        // 从SharedPreferences中获取token
        SharedPreferences sharedPreferences = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        String token = sharedPreferences.getString(key, null);
        return token;
    }

    public static void saveTokenToSharedPreferences(Context context, String key, String token) {
        // 将token保存到SharedPreferences中
        SharedPreferences sharedPreferences = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, token);
        editor.apply();
    }

    /**
     * 删除SharedPreferences中的key
     *
     * @param context
     * @param key
     */
    public static void deleteTokenFromSharedPreferences(Context context, String key) {
        // 从SharedPreferences中删除token
        SharedPreferences sharedPreferences = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.remove(key);
    }

    public interface Listener {
        void unLogin();
    }
}
